// copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
// see COPYRIGHT for reuse legalities
//

#import "WW3DShapeBrowser.h"
#import "WW3DShapeCell.h"
#import "WW3DShapeMatrix.h"
#import "WW3DShape.h"
#import "WW3DCamera.h"
#import "WW3DWell.h"
#import "WW3DShader.h"
#import "WW3DShapeControlPanel.h"

@implementation WW3DShapeBrowser

- initFrame:(const NXRect *)r 
{
   self = [super initFrame:r];
   [self setCellClass:[WW3DShapeCell class]];
   [self setMatrixClass:[WW3DShapeMatrix class]];
   [self setDelegate:self];
   [self setMultipleSelectionEnabled:NO];
   [self setTarget:self];
   [self setAction:@selector(singleClick:)];
   [self setDoubleAction:@selector(doubleClick:)];
   shapeControlPanel = [[WW3DShapeControlPanel alloc] init];
   return self;
}

- awake
{
   [super awake];

   [self setCellClass:[WW3DShapeCell class]];
   [self setMatrixClass:[WW3DShapeMatrix class]];
   [self setDelegate:self];
   [self setMultipleSelectionEnabled:NO];
   [self setTarget:self];
   [self setAction:@selector(singleClick:)];
   [self setDoubleAction:@selector(doubleClick:)];
   shapeControlPanel = [[WW3DShapeControlPanel alloc] init];

   return self;
}

- free
{
  if (shapeControlPanel)
  {  [shapeControlPanel free];
  }
  return [super free];
}

- (BOOL)acceptsFirstResponder { return YES; }

- selectRootShape
{
   [[self matrixInColumn:0] selectCellAt:0 :0];
   [self singleClick:[self matrixInColumn:0]];
   return self;
}

- singleClick:sender
{
  [[ribWell camera] setCurrentShape:[[sender selectedCell] shape]];
  [ribWell revertShapeInspectorFor:[[sender selectedCell] shape]];
  return self; 
}

- updateShapeCamera
{
  [[ribWell camera] display];
  return self; 
}

- doubleClick:sender
{
  [[sender selectedCell] setEditable:YES];
  return self; 
}

- (int)browser:sender fillMatrix:matrix inColumn:(int)column
{
  int	row, howMany;
  id	shapeCell, child, sibling, currentShape;
	

  // In order to fill in a given column, we need to know what the
  // currently selected cell in the column before it is.
  // once we know that, we can query it for it's immediate children.
  [matrix setBrowser:self];
  currentShape = [[self selectedCell] shape];
  if (!currentShape)  // if there is no selection
  {  currentShape = [[ribWell camera] worldShape]; 
     [matrix addRow];
     shapeCell = [matrix cellAt:0 :0];	
     [shapeCell setStringValue:[currentShape shapeName]];
     [shapeCell setShape:currentShape];
     [shapeCell setLoaded:YES];
     if ([[currentShape children] count])
     {  [shapeCell setLeaf:NO];
     }
     else
     {  [shapeCell setLeaf:YES];
     }
     howMany = [[currentShape siblings] count];
     for (row = 0; row < howMany; row++)
     {  [matrix addRow];
        sibling = [[currentShape siblings] objectAt:row];
        shapeCell = [matrix cellAt:(row+1) :0];	
        [shapeCell setStringValue:[sibling shapeName]];
        [shapeCell setShape:sibling];
        [shapeCell setLoaded:YES];
        if ([[sibling children] count])
        {  [shapeCell setLeaf:NO];
        }
        else
        {  [shapeCell setLeaf:YES];
        }
     }
     howMany++;  // to account for the first one
  } 
  else
  {  howMany = [[currentShape children] count];
     for (row = 0; row < howMany; row++)
     {  [matrix addRow];
        child = [[currentShape children] objectAt:row];
        shapeCell = [matrix cellAt:row :0];	
        [shapeCell setStringValue:[child shapeName]];
        [shapeCell setShape:child];
        [shapeCell setLoaded:YES];
        if ([[child children] count])
        {  [shapeCell setLeaf:NO];
        }
        else
        {  [shapeCell setLeaf:YES];
        }
     }
  }
  [[[ribWell camera] worldShape] setSelected:NO andDrawOrigin:NO];
  [[[self selectedCell] shape] setSelected:YES andDrawOrigin:[[ribWell camera] drawOriginForSelectedShape]];
  
  // need a flag for this; for now, let's not redisplay 
  //[ribWell display];

  return howMany;
}

- wellWasUpdated:well
{
  [self loadColumnZero];
  return self;
}

@end
